// ==ClosureCompiler==
// @output_file_name default.js
// @compilation_level SIMPLE_OPTIMIZATIONS
// ==/ClosureCompiler==

Backbone.TreeNodeModel = Backbone.Model.extend({
    defaults: {
        title: 'Unknown',
        parent : null
    },
    getParentId: function() { return this.get('node_parent'); },
    isRoot: function() { return (!this.getParentId() || this.getParentId()=='0'); },
    isChildOf: function(parentid) {
        return (!parentid) ?  this.isRoot() : (parentid == this.getParentId());
    }
});

Backbone.TreeNodeCollection = Backbone.Collection.extend({
    model: Backbone.TreeNodeModel,
    getChildren: function(parentid) {
        return this.filter( function(model) {return model.isChildOf(parentid)}, this);
    }
});

Backbone.TreeNodeView = Backbone.View.extend({
    tagName: 'li',
    template: _.template('<span class="node-collapse"> <%- title %> <span>'),
    initialize: function() {
        //console.log(this.options.nodetemplate);
        if (this.options.nodetemplate) {
            this.template = _.template($(this.options.nodetemplate).html());
        }
        this.model.on('destroy', this.remove, this);
        this.model.on('change', this.render, this);
        this.collapsed = this.options.collapsed;
    },
    collapse_speed: 300,
    events:{
        "click > .node-collapse .node-label" : "toggleCollapse",
        "click > .node-collapse .node-data" : "toggleCollapse"
    },
    hasChild: function() { return this.$el.has('ul').length },
    toggleCollapse: function($event) {
        if (this.hasChild()) {
            this.collapsed = !this.collapsed;
            if (this.collapsed) {
                this.$('> .node-collapse i').attr('class', 'icon-plus');
                this.$('> .node-tree').slideUp(this.collapse_speed);
            } else {
                this.$('> .node-collapse i').attr('class', 'icon-minus');
                this.$('> .node-tree').slideDown(this.collapse_speed);  
            }
        }
    },
    render: function() {
        var template = this.template(this.model.toJSON());
        this.$el.empty().html(template);
        return this;
    }
});

Backbone.TreeNodeCollectionView = Backbone.View.extend({
    tagName: 'ul',
    className: 'nav navi-list',
    nodeid:null,
    initialize: function() {
        this.nodeid = (!this.options.nodeid || this.options.nodeid=='0') ? null : this.options.nodeid;
        this.collapsed = this.options.collapsed;
    },
    isRoot: function(nodeid) { return (!nodeid || nodeid=='0'); },
    update: function() {
        this.$el.empty();
        var root = this.isRoot(this.nodeid);
        if (!root) {
            this.$el.addClass('node-tree');
        }
    },
    renderChild: function(parentNode, node) {
        var children = this.collection.getChildren(node.id);
        if (children.length > 0) {
            var treeNodeCollectionView = new Backbone.TreeNodeCollectionView({
                collection: this.collection,
                nodetemplate: this.options.nodetemplate,
                collapsed: this.collapsed,
                nodeid : node.id});
            parentNode.$el.append(treeNodeCollectionView.render().el);
            if (this.collapsed) {
                parentNode.$el.find('> ul').hide();  
            } else {
                parentNode.$el.find('> ul').show();  
            }
        }
        if (children.length > 0) {
            var collapsedClass = (this.collapsed) ? '<i class="icon-plus"/>' : '<i class="icon-minus"/>';
            parentNode.$el.find('> .node-collapse').prepend($(collapsedClass));
        } else {
            parentNode.$el.find('> .node-collapse').prepend($('<i class=" icon-file"/>'));
        }
    },
    render: function() {
        var list = this.collection.getChildren(this.nodeid);
        this.update();
        _.each(list, function(treeNode){
            var treeView = new Backbone.TreeNodeView({
                model : treeNode,
                collapsed: this.collapsed,
                nodetemplate: this.options.nodetemplate
            });
            var parentNode = treeView.render();
            this.$el.append(parentNode.el);
            this.renderChild(parentNode, treeNode);
        }, this);
        return this;
    }
});
